// Copyright  1993-1996 by Apple Computer, Inc.  All rights reserved.
// listPicker defs



// used to define the pickerDef at compile time.  May include all of the slots for the pickerDef.
// In the listPicker.pickerDef proto to this DataDef.  
DefConst('kMyBasicDataDef,{
	_proto: protoNameRefDataDef,				// required
	name:  "My Data Editor",					//name at top left of picker
	editTitle:  "New Data for Second",		//Title at top of defaultOpenEditor slip (optional)
	
	// method used to determine if a popup menu should appear 
	MakePopup: func(nameRef, fieldPath)
			begin
				if fieldPath = 'second then
				begin
					local pop := array(3, nil);
					pop[0]:= Clone(nameRef.second);
					pop[1]:= 'pickSeparator;
					pop[2]:= "Change...";
					pop;
				end;
			end,
			
	// default PopVal method assumes that the popup is an array of frames
	// specialize the method for a picked item that is just a string	
	PopVal: func(item)
	begin
		if ClassOf(item) = 'frame then
			inherited:PopVal(item) ;
		else
			item;
	end,
			
	// support selecting edit of existing data from the popUp menu.  The only way that you can edit 
	// existing valid data from a listPicker is to call an openEditor function from a popUp menu.
	// called when an item is selected from a popup
	// NOTE: since only one column pops a menu we do not need to check which
	//			popup a selection occured in
	PickActionScript:  func(popIndex, tapInfo, context)
	begin
		local popup := tapInfo.popup;
		local nameRef := tapInfo.nameRef;
		local fieldPath := tapInfo.fieldPath;
		local value := self:PopVal(popup[popIndex]);  //the item that is selected from the popUp list.

		if StrEqual(value,"Change...") AND (self.OpenEditor OR validationFrame) then
		begin
			// stash it so we can restore if they don't enter any info
			tapInfo.cryoNameRefData := deepClone(nameRef.(fieldPath));
			nameRef.(fieldPath) := nil;

			tapInfo.editPaths := [fieldPath];
			_selectOnly := true;

			// this is where you could call your own editor.
			if self.OpenEditor then
				self:OpenEditor(tapInfo, context, 'edit);
			else
				self:DefaultOpenEditor(tapInfo, context, 'edit);
		end
		else 
		begin
			nameRef.(fieldPath) := value;
			context:Tapped('select);
		end;
	end,

	// the following stuff is required for validation
	Validate: func(nameRef, pathArray)
	begin
		// keep track of any paths that fail
		local failedPaths := [];
		foreach index, path in pathArray do
		begin
			// very simple test since each path is
			// is supposed to be a string
			// your test may be more complex and call
			// other methods to verify particular types of data
			if NOT :ValidateString(nameRef, path) then
				AddArraySlot(failedPaths, path) ;
			// return the failedPaths or an empty array
		end;
		return failedPaths ;	
	end,
	
	// my own utility function to make sure the string is valid
	// used :Validate above
	ValidateString: func(nameRef, path)
	begin
		// try and get the data from the nameRef
		local realData := nameRef.(path) ;
		
		// if not data in the nameRef, try and get
		// the entry and get the data from it
		if NOT realData then
		begin
			entry := EntryFromObj(nameRef) ;
			if entry then
			begin
				realData := entry.(path) ;
				nameRef.(path) := realData ;
			end ;
		end ;
		
		// valid if the value is non-NIL and is a filled string
		return realData AND IsString(realData) AND StrFilled(realData) ;
	end,
	
	
	// provide this method to open an edit slip for
	// a new or editited item.
	OpenEditor: func(tapInfo, context, why)
	begin
		local valid := :Validate(tapInfo.nameRef, tapInfo.editPaths) ;
		
		// check to see if the nameRef is valid to figure out
		// what to do
		if (length(valid) > 0) then
		begin
			// if not valid, open the editor
			return GetLayout("editor.t"):New(tapinfo.nameRef,
				tapInfo.editPaths, why, self, 'EditDone, context) ;
		end
		else begin
			// just toggle the selection and return nil
			context:Tapped('toggle) ;
			return nil ;
		end ;
	end,
	
	// this is a utility method that is not part of the required
	// methods. Once the editor is closed, this method gets
	// called so we can update the listPicker appropriately
	EditDone: func(nameRef, editPaths, context, why)
	begin
		// check to see if the edited item is valid
		if NOT :Validate(nameRef, editPaths) then
			// not valid so remove the checkmark (if any)
			context:Tapped(nil);
		else begin
			// is valid, so see if editing or a new item
			if why = 'edit then
			begin
				// change the actual entry
				// an edit occurs when the entry that is clicked
				// on does not Validate.
				local entry := EntryFromObj(nameRef) ;
				if entry then
				begin
					entry.first := nameRef.first ;
					entry.second := nameRef.second ;
					EntryChangeXMIT(entry, kAppSymbol) ;
				end ;
				
				// The nameRef was valid, so select it.
				context:Tapped('select);
			end
			else begin
				// a new data item so add entry to soup
				local newEntry := Clone(kCanonicalEntry) ;
				newEntry.first := nameRef.first ;
				newEntry.second := nameRef.second ;

				GetUnionSoupAlways(kSoupName):AddToDefaultStoreXMIT(newEntry, kAppSymbol) ;
				
				// tell the listpicker to update its information
				context:Update() ;
			end ;
		end ;
	end,
	
	});
	

//************

/*
	removed validationFrame slot from data def
*/

